#if UNITY_EDITOR

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
public partial class Startup
{
#if HybridCLR
    private static void CreateHotfixFile()
    {

        /**
{
    "Assembly": "https://url/IPhonePlayer/Assembly/1/",
    "AssetBundle": "https://url/IPhonePlayer/AssetBundle/1/"
}
        **/
        RuntimePlatform platform = Application.platform;
        var buildTarget = UnityEditor.EditorUserBuildSettings.activeBuildTarget;
        if (buildTarget == UnityEditor.BuildTarget.Android)
        {
            platform = RuntimePlatform.Android;
        }
        else if (buildTarget == UnityEditor.BuildTarget.iOS)
        {
            platform = RuntimePlatform.IPhonePlayer;
        }
        else if (buildTarget == UnityEditor.BuildTarget.StandaloneWindows)
        {
            platform = RuntimePlatform.WindowsPlayer;
        }
        else if (buildTarget == UnityEditor.BuildTarget.StandaloneWindows64)
        {
            platform = RuntimePlatform.WindowsPlayer;
        }
        else if (buildTarget == UnityEditor.BuildTarget.WebGL)
        {
            platform = RuntimePlatform.WebGLPlayer;
        }
        var AssemblyUri = new Uri(Path.Combine(ManifestRoot, platform.ToString(), "Assembly", VERSION)).AbsoluteUri;
        var AssetBundleUri = new Uri(Path.Combine(ManifestRoot, platform.ToString(), "AssetBundle", VERSION)).AbsoluteUri;
        var builder = new StringBuilder();
        builder.AppendLine("{");
        builder.AppendLine("\t\"Assembly\": \"" + AssemblyUri + "\",");
        builder.AppendLine("\t\"AssetBundle\": \"" + AssetBundleUri + "\"");
        builder.AppendLine("}");
        var hotfixRoot = new Uri(Path.Combine(Application.dataPath, "../", "Hotfix")).AbsolutePath;
        var hotfixPath = new Uri(Path.Combine(Application.dataPath, "../", "Hotfix", platform.ToString())).AbsolutePath;
        if (!Directory.Exists(hotfixPath))
        {
            Directory.CreateDirectory(hotfixPath);
        }
        var jsonPath = Path.Combine(hotfixPath, "debug.json");
        File.WriteAllText(jsonPath, builder.ToString());
        var v = Path.Combine(hotfixPath, "Assembly", VERSION);
        if (Directory.Exists(v))
        {
            Directory.Delete(v, true);
        }
        CopyFolder(Path.Combine(Application.streamingAssetsPath, HotfixLoader.dllsFolder), Path.Combine(v, HotfixLoader.dllsFolder));
        var aotFiles = HybridCLR.Editor.Settings.HybridCLRSettings.Instance.patchAOTAssemblies;
        foreach (var item in aotFiles)
        {
            var srcName = string.Format("{0}.bytes", item);
            if (File.Exists(Path.Combine(v, HotfixLoader.dllsFolder, srcName)))
            {
                // File.Delete(Path.Combine(v, HotfixLoader.dllsFolder, srcName));
            }
        }
        string[] files = System.IO.Directory.GetFiles(Path.Combine(v, HotfixLoader.dllsFolder));
        foreach (var file in files)
        {
            if (file.EndsWith(".meta"))
            {
                File.Delete(file);
            }
        }


        v = Path.Combine(hotfixPath, "AssetBundle", VERSION);
        if (!Directory.Exists(v))
        {
            Directory.CreateDirectory(v);
        }
        Debug.LogWarning("hotfix assets : " + hotfixPath);
        if (File.Exists(Path.Combine(hotfixRoot, platform.ToString() + ".txt")))
        {
            var s = File.ReadAllLines(Path.Combine(hotfixRoot, platform.ToString() + ".txt"));
            foreach (var line in s)
            {
                Debug.LogError("copy " + hotfixPath + " to " + new Uri(line).AbsolutePath);
                CopyFolder(hotfixPath, new Uri(line).AbsolutePath);
            }
        }

    }

    [UnityEditor.MenuItem("HybridCLR/更新资源", false, 1)]
    public static void copyAll()
    {
        //HybridCLR.Editor.Commands.PrebuildCommand.GenerateAll();
        var defs = HybridCLR.Editor.Settings.HybridCLRSettings.Instance.hotUpdateAssemblyDefinitions;
        if (defs == null || defs.Length < 1)
        {
            Debug.LogError("没有设置更新程序集");
            return;
        }
        var btimePath = Path.Combine(Application.dataPath, "Game/Scripts/BuildTime.cs");
        var editorStr = string.Empty;
        if (File.Exists(btimePath))
        {
            editorStr = File.ReadAllText(btimePath);
            var time = DateTime.Now;
            var t1 = editorStr.IndexOf("\"");
            if (t1 != -1)
            {
                var t2 = editorStr.IndexOf("\"", t1 + 1);
                if (t2 != -1)
                {
                    var s = editorStr.Substring(0, t1 + 1) + time.ToString() + editorStr.Substring(t2);
                    File.WriteAllText(btimePath, s);
                }
            }
        }
        // AssetDatabase.Refresh();
        // UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation();
        var src = Path.Combine(HybridCLR.Editor.SettingsUtil.ProjectDir, HybridCLR.Editor.SettingsUtil.AssembliesPostIl2CppStripDir, UnityEditor.EditorUserBuildSettings.activeBuildTarget.ToString());
        var dst = Path.Combine(Application.streamingAssetsPath, HotfixLoader.dllsFolder);
        if (!Directory.Exists(dst))
        {
            Directory.CreateDirectory(dst);
        }

        var config = new HotfixInfo();
        var metadataFiles = HybridCLR.Editor.Settings.HybridCLRSettings.Instance.patchAOTAssemblies;
        var list = new List<DllFileInfo>();
        /*
        mscorlib
        System
        System.Core
        Unity.InputSystem
        */
        if (metadataFiles != null)
        {
            foreach (var item in metadataFiles)
            {
                var srcName = string.Format("{0}.dll", item);
                var dstName = string.Format("{0}.bytes", item);
                if (!File.Exists(Path.Combine(src, srcName)))
                {
                    Debug.LogError("先执行 GenerateAll");
                    return;
                }
                var bytes = File.ReadAllBytes(Path.Combine(src, srcName));
                var info = new DllFileInfo();
                info.Size = bytes.Length;
                info.FileName = dstName;
                byte[] retVal = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(bytes);
                var sb = new StringBuilder();
                for (int i = 0; i < retVal.Length; i++)
                {
                    sb.Append(retVal[i].ToString("x2"));
                }
                info.Version = sb.ToString();
                list.Add(info);
                File.Copy(Path.Combine(src, srcName), Path.Combine(dst, dstName), true);
            }
        }

        config.MetadataFiles = list.ToArray();
        list.Clear();
        HybridCLR.Editor.Commands.CompileDllCommand.CompileDllActiveBuildTarget();

        src = Path.Combine(HybridCLR.Editor.SettingsUtil.ProjectDir, HybridCLR.Editor.SettingsUtil.GetHotUpdateDllsOutputDirByTarget(UnityEditor.EditorUserBuildSettings.activeBuildTarget));

        foreach (var def in defs)
        {
            var item = def.name;
            var srcName = string.Format("{0}.dll", item);
            var dstName = string.Format("{0}.bytes", item);

            if (File.Exists(Path.Combine(src, srcName)))
            {
                var bytes = File.ReadAllBytes(Path.Combine(src, srcName));
                var info = new DllFileInfo();
                info.FileName = dstName;
                info.Size = bytes.Length;
                byte[] retVal = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(bytes);
                var sb = new StringBuilder();
                for (int i = 0; i < retVal.Length; i++)
                {
                    sb.Append(retVal[i].ToString("x2"));
                }
                info.Version = sb.ToString();
                list.Add(info);

                File.Copy(Path.Combine(src, srcName), Path.Combine(dst, dstName), true);
            }
        }
        if (list.Count < 1)
        {
            Debug.LogError("没有找到更新程序集");
            return;
        }
        config.HotfixFiles = list.ToArray();
        config.BuildTime = DateTime.Now.ToString();
        config.MainAssembly = list[0].FileName;
        var json = JsonUtility.ToJson(config);
        File.WriteAllText(Path.Combine(dst, HotfixLoader.configFile), json);
        CreateHotfixFile();
        Debug.LogWarningFormat("更新完成");
        // Debug.LogError(editorStr);
        if (File.Exists(btimePath))
        {
            File.WriteAllText(btimePath, editorStr);
        }
    }
    public static int CopyFolder(string sourceFolder, string destFolder)
    {
        try
        {
            //如果目标路径不存在,则创建目标路径
            if (!System.IO.Directory.Exists(destFolder))
            {
                System.IO.Directory.CreateDirectory(destFolder);
            }
            //得到原文件根目录下的所有文件
            string[] files = System.IO.Directory.GetFiles(sourceFolder);
            foreach (string file in files)
            {
                string name = System.IO.Path.GetFileName(file);
                string dest = System.IO.Path.Combine(destFolder, name);
                if (File.Exists(dest))
                {
                    File.Delete(dest);
                }
                System.IO.File.Copy(file, dest);//复制文件
            }
            //得到原文件根目录下的所有文件夹
            string[] folders = System.IO.Directory.GetDirectories(sourceFolder);
            foreach (string folder in folders)
            {
                string name = System.IO.Path.GetFileName(folder);
                string dest = System.IO.Path.Combine(destFolder, name);
                CopyFolder(folder, dest);//构建目标路径,递归复制文件
            }
            return 1;
        }
        catch (Exception)
        {
            return -1;
        }
    }
#endif
}
#endif